﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Windows.Forms;


namespace Tzync
{
   public class Rollback
    {
        private long allocatedSize; // 200 Mb allocated to store rollback files
        private Queue<RollbackFile> RollbackQueue;
        private long spaceRemaining;
        private List<RollbackFile> FileList, DeleteList;
        private SystemType sys;
        Utility util = new Utility();
        private string RollPath;
        private List<string> Paths;
        
        public Rollback()
        {
            allocatedSize = 200 * 1024 * 1024;
            spaceRemaining = 200 * 1024 * 1024;
            RollbackQueue = new Queue<RollbackFile>();
            //SystemType sys = new SystemType();
            FileList = new List<RollbackFile>();
            DeleteList = new List<RollbackFile>();
            RollPath = @"C:\Tzync\";
            Paths = new List<string>();
        }

        /*public void loadMetadata(List<TreeNode> arrNodes)
        {
            int id;
            string fullpath;
            Pair<int, int> version;
            DateTime lastSyncTime;
            String macFile = Directory.GetCurrentDirectory();
            macFile = Path.Combine(macFile, @"Tzync\MacFile.txt");
            TextReader tr;
            String input = "";
            int counter = 0;
            String temp = util.GetCPUId();
            String MacA = "", MacB;
            if (File.Exists(macFile))
            {
                // open file
                tr = new StreamReader(macFile);
                while ((input = tr.ReadLine()) != null)
                {
                    if (input.Trim().Length != 0)
                    {
                        if (counter == 0) MacA = input;
                        if (counter == 1) MacB = input;
                        counter++;
                    }
                }
                // close the stream
                tr.Close();
                if (temp == MacA)
                    sys = SystemType.Host;
                else
                  sys = SystemType.Guest;
            }
            RollbackFile RF = new RollbackFile();
            RF.setSysType(sys);
            FileList = new List<RollbackFile>();
            for (int i = 0; i < arrNodes.Count(); i++)
            {
                long size1=0;
                RF.setid(arrNodes[i].getId());
                if (sys == SystemType.Host)
                {
                    RF.setPath(arrNodes[i].getFullPathA());
                    RF.setST(arrNodes[i].getSyncA());
                    RF.setSize(arrNodes[i].getSizeA());
                    RF.setVersion(arrNodes[i].getVersionA());
                    size1 = arrNodes[i].getSizeA();
                }
                else if (sys == SystemType.Guest)
                {
                    RF.setPath(arrNodes[i].getFullPathB());
                    RF.setST(arrNodes[i].getSyncB());
                    RF.setSize(arrNodes[i].getSizeB());
                    RF.setVersion(arrNodes[i].getVersionB());
                    size1 = arrNodes[i].getSizeB();
                }
                FileList.Add(RF);
                RollbackQueue.Enqueue(RF);
                spaceRemaining-= size1;
                
            }
        }*/
        public void addRollbackFile(List<Difference> DiffList, List<TreeNode> arrNodes)
        {
            string folderName;
            folderName = arrNodes[0].getName();
            string pathRoll = Path.Combine(@"C:\Tzync\Rollback\", folderName);
            if (!Directory.Exists(pathRoll))
            {
                Directory.CreateDirectory(pathRoll);
            }

            string newPath;

            //MessageBox.Show(DiffList.Count().ToString());
            long size1=0;
            FileInfo temp;
            List<FileInfo> Diff = new List<FileInfo>();
            RollbackFile RF = new RollbackFile();
            for (int i = 0; i < DiffList.Count(); i++)
            {
                
                if (sys == SystemType.Host && DiffList[i].GetPartnerFile() != null && DiffList[i].GetItemType() == Type.File)
                {
                    size1 = DiffList[i].GetPartnerFile().getSizeA();
                    RF.setid(DiffList[i].GetPartnerFile().getId());
                    RF.setPath(DiffList[i].GetPartnerFile().getFullPathA());
                    RF.setVersion(DiffList[i].GetPartnerFile().getVersionA());
                    RF.setST(DiffList[i].GetPartnerFile().getSyncA());
                    RF.setSysType(SystemType.Host);
                    RF.setName(DiffList[i].GetPartnerFile().getName());
                    RF.setSize(DiffList[i].GetPartnerFile().getSizeA());
                }
                else if (sys == SystemType.Guest && DiffList[i].GetPartnerFile() != null && DiffList[i].GetItemType() == Type.File)
                {
                    size1 = DiffList[i].GetPartnerFile().getSizeB();
                    RF.setid(DiffList[i].GetPartnerFile().getId());
                    RF.setPath(DiffList[i].GetPartnerFile().getFullPathB());
                    RF.setVersion(DiffList[i].GetPartnerFile().getVersionB());
                    RF.setST(DiffList[i].GetPartnerFile().getSyncB());
                    RF.setSysType(SystemType.Guest);
                    RF.setSize(DiffList[i].GetPartnerFile().getSizeB());
                }
                if (DiffList[i].GetPartnerFile() != null && DiffList[i].GetItemType() == Type.File)
                {
                    FileList.Add(RF);
                    temp = new FileInfo(RF.getPath());
                    newPath = Path.Combine(pathRoll, RF.getName());
                    temp.CopyTo(newPath,true);
                    Paths.Add(newPath);
                    RollbackQueue.Enqueue(RF);
                    spaceRemaining -= size1;
                }
            }
        }

      /*  public void backupRoll()
        {
            List<FileInfo> DiffList;
            DiffList = new List<FileInfo>();

            for (int i = 0; i < FileList.Count(); i++)
            {
                DiffList[i] = new FileInfo(FileList[i].getPath());
                DiffList[i].CopyTo(RollPath);
            }

        }*/

        public void reviewQueue(List<Difference> DiffList)
        {
            if (DiffList != null)
            {
                RollbackFile RF = new RollbackFile();
                long size1 = 0;
                for (int i = 0; i < DiffList.Count(); i++)
                {
                    if (sys == SystemType.Host)
                        size1 += DiffList[i].GetPartnerFile().getSizeA();
                    else if (sys == SystemType.Guest)
                        size1 += DiffList[i].GetPartnerFile().getSizeB();
                }

                if (size1 > spaceRemaining)
                {
                    while (spaceRemaining < size1)
                    {
                        RF = RollbackQueue.Dequeue();
                        DeleteList.Add(RF);
                        spaceRemaining += RF.getSize();
                    }
                }
            }
        }

        public void DeleteOld()
        {
            List<FileInfo> DelList = new List<FileInfo>();
            for (int i = 0; i < DeleteList.Count(); i++)
            {
                DelList[i] = new FileInfo(DeleteList[i].getPath());
                DelList[i].Delete();
            }
        }

        public Queue<RollbackFile> returnRoll()
        {
            return RollbackQueue;
        }


        public void UpdateRollMeta()
        {
            //MessageBox.Show(RollbackQueue.Count().ToString());
            if (RollbackQueue.Count() > 0)
            {
            Queue<RollbackFile> newQueue = new Queue<RollbackFile>(RollbackQueue);

            List<RollbackFile> metaList = new List<RollbackFile>() ;

                int p=-1;
                if(sys == SystemType.Guest)
                    p=1;
                else if(sys == SystemType.Host)
                    p=0;

                for (int i = 0; i < newQueue.Count(); i++)
                {
                    metaList.Add( newQueue.Dequeue());
                }
                for (int j = metaList.Count()-1; j >= 0; j--)
                    using (StreamWriter metaFile = new StreamWriter(@"C:\Tzync\Rollback\RollbackMeta", true))
                    {
                        metaFile.WriteLine(metaList[j].getPath() + "," + metaList[j].getLastSyncTime().ToString() + "," + metaList[j].getId().ToString() + "," + p.ToString());

                    }
            }

        }


        public void performRollback(List<string> RollList)
        {
            List<FileInfo> FileList = new List<FileInfo>();
            for (int i = 0; i < RollList.Count(); i++)
            {
                FileList[i] = new FileInfo(Paths[i]);
                FileList[i].MoveTo(RollList[i]);
            }
        }



     


    }
}
